package javaapplication1;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.util.ArrayList;
import java.util.LinkedList;
/**
 *
 * @author Dron
 */

class Hash_Elem
{
    int count;
    String Name;
    
    Hash_Elem (String _Name, int _count)
    {
        Name = _Name;
        count = _count;
    }
}
 
        
public class Hash 
{
      private ArrayList<LinkedList<Hash_Elem>> H;
      private int max_num_of_col = 0;
      
      int num_of_words = 0;//, num_of_resizes = 0;
      
      Hash(int count)
      {
          H = new ArrayList<LinkedList<Hash_Elem>>();
          for (int i = 0; i < count; i++)
          {
             H.add(new LinkedList<Hash_Elem>());
          }
      }
      
      int size()
      {
          return H.size();
      }
      
    	int Add(char t[])
	{
            return Add(new Hash_Elem(new String(t), 1));
        }
      
    	int Add(Hash_Elem _H)
	{            
                char t[] = _H.Name.toCharArray();
                int _count = _H.count;
                
		int k = conv(t);
                int pos = -1;
                
		for (int i = 0; i < (H.get(k)).size(); i++)
                {
                    if (  ((H.get(k)).get(i)).Name.equals(new String(t))  ) pos = i;
                }
                
		if (pos != -1)
                {
                    ((H.get(k)).get(pos)).count+=_count;              
                }
		else
                {
                    (H.get(k)).add(new Hash_Elem(new String(t), 1));
                }
                
                num_of_words++;
                max_num_of_col = Math.max(max_num_of_col, (H.get(k)).size());
                
                if (num_of_words > H.size()/2)
                {    
                    int _max_num_of_col = max_num_of_col;
                    max_num_of_col = 0;
                    resize(H.size()*8);
                    return _max_num_of_col; 
                }
                return 0;
	}

	int conv(char l[])
	{
		int k = 0;
		for (int i=0; i<l.length; i++)
		{
			k += l[i] * Math.pow(8.0, i);
		}
		return Math.abs(k)%H.size();
	}
        
        int conv2(char l[])
	{
		int k = 0;
		for (int i=0; i<l.length; i++)
		{
			k += l[i] * Math.round(Math.exp(i));
		}
		return Math.abs(k)%H.size();
	}

	int GetCount(char t[])
	{
                int k = conv(t);
                int pos = -1;
                 
		for (int i = 0; i < (H.get(k)).size(); i++)
                {
                    if (  ((H.get(k)).get(i)).Name.equals(new String(t))  ) pos = i;
                }
		                 
		if (pos != -1)
                {
                    return ((H.get(k)).get(pos)).count;
                }
		else
                {
                    return 0;
                }
	}
        
        private void resize(int n)
        {
            int old_size = H.size();
            for (int i = 0; i < (n - old_size); i++)
            {
                H.add(new LinkedList<Hash_Elem>());
            }
            int _pos;
            for (int i = 0; i < old_size; i++)
            {
                for (int j = 0; j < (H.get(i)).size(); j++)
                {
                    if ((H.get(i)).size() != 0)
                    {
                        _pos = conv(H.get(i).get(j).Name.toCharArray());
                        
                        if (_pos != i)
                        {
                            Hash_Elem removed = (H.get(i)).remove(j); 
                            num_of_words--;
                            Add(removed);
                        }
                  
                    }
                }
            }
        }
}
